var sys = require("util"),         //lower version sys = require("sys")
    tls = require("tls"),
    fs  = require("fs"),
    url = require("url"),
 	Buffer = require('buffer').Buffer;

exports.createServer = function(cert_path, keys_path, host, port) {
	var options = {};
	options.cert_path = cert_path;
	options.keys_path = keys_path;
	options.host = host || 'gateway.sandbox.push.apple.com';
	options.port = port || 2195;

	var server = new APNS(options);

	return server;
};

APNS = function(options) {
	var keyPem 	= fs.readFileSync(__dirname+"/"+options.keys_path);
	var certPem = fs.readFileSync(__dirname+"/"+options.cert_path);
	var cred = { key:keyPem, cert:certPem };
	this.client = this.connect(options.port, options.host, cred);
};

APNS.prototype.connect = function(port, host, cred) {
	var self = this;
	var client = tls.connect(port, host, cred, function() {
		if (client.authorized) {
			self.waiting_buffers.forEach(function(b){
				client.write(b);
			});
			self.waiting_buffers = [];
		} else {
			console.log(client.authorizationError);
			client.end();
		}
	});
	self.waiting_buffers = [];

	client.setEncoding('utf8');
	client.setTimeout(0);
	//client.setKeepAlive(true, 0);
	client.on('data', function(data) { 
		console.log("data: "+data); 
	});
	client.on('error', function(error) {
		console.log("FAIL: "+error+" "+this.waiting_buffers);
		client.destroy();
		console.log(port+" "+host);
		self.connect(port, host, cred);
	});
	client.on('close', function(error) {
		console.log("close: "+error);
		console.log(port+" "+host);
		self.connect(port, host, cred);
	});

	return client;
};

APNS.prototype.notify = function(device_id, obj, other) {
	var json = (JSON.stringify({'aps':obj,"other":other})).replace(/\\\\/ig, '\\');
	//到了这里 json中已经包含有中文汉字，而不是原生json_encode后的数据.
	device_id = device_id.replace(/\s/g, '');  
	console.log(json);
	//var buffer = this.notification_buffer(device_id, json);
	var buffer = this.notification_buffer(device_id, json);
	if (this.client.readyState == 'open') {
		this.client.write(buffer);
	} else {
		this.waiting_buffers.push(buffer);
	}
	return this;
};

APNS.prototype.HEXpack = function(str){
	var p=[];
	for (var i=0;i<str.length;i=i+2) { p.push(parseInt(str[i]+str[i+1], 16)); }
	return p;
};

APNS.prototype.ASCIIpack = function(str){
	var p=[];
	for (var i=0;i<str.length;i++) { p.push(str.charCodeAt(i)); }
	return p;
};

APNS.prototype.notification_buffer = function(device_id, json) {
	//var a = [0,0,32].concat( this.HEXpack(device_id), [0,json.length], this.ASCIIpack(json) );

	var json_len = Buffer.byteLength(json);
	var a = [0,0,32].concat( this.HEXpack(device_id), [0,json_len] );
	var buffer = new Buffer(a.length+json_len);
	var count = 0;
	a.forEach(function(e) {
		buffer[count] = e;
		count++;
	});
	buffer.write(json,a.length);
	return buffer;
};

APNS.prototype.end = function() {
	this.client.end();
}
